package com.atom.annotation.bean;

import com.atom.annotation.api.ApiImplProvider;

import java.util.HashMap;
import java.util.Map;


public abstract class ApiImpls {

    private final Map<Class<?>, ApiImplsMap<?>> mApiImpsMap = new HashMap<>();
    private final Map<Class<?>, Class<? extends ApiImplProvider>> mApiImpsWithProviderMap = new HashMap<>();

    public ApiImpls() {
    }

    protected <T> void add(String name, Class<T> apiClass, Class<? extends T> implClass, long version) {
        ApiImplsMap<T> implsMap;
        synchronized (mApiImpsMap) {
            ApiImplsMap<?> apiImplsMap = mApiImpsMap.get(apiClass);
            if (apiImplsMap == null) {
                implsMap = new ApiImplsMap<>();
                mApiImpsMap.put(apiClass, implsMap);
            } else {
                implsMap = (ApiImplsMap<T>) apiImplsMap;
            }
        }
        implsMap.put(implClass, new ApiImplWrapper<T>(apiClass, implClass, name, version));
    }

    @SuppressWarnings("unchecked")
    public <T> Map<Class<? extends T>, ApiImplWrapper<T>> getApiImpls(Class<T> apiClass) {
        synchronized (mApiImpsMap) {
            return (ApiImplsMap<T>) mApiImpsMap.get(apiClass);
        }
    }

    private static class ApiImplsMap<T> extends HashMap<Class<? extends T>, ApiImplWrapper<T>> {

    }

    protected  void addProvider(Class<?> implClass, Class<? extends ApiImplProvider> implProvider) {
        synchronized (mApiImpsWithProviderMap) {
            mApiImpsWithProviderMap.put(implClass, implProvider);
        }
    }


    @SuppressWarnings("unchecked")
    public Class<? extends ApiImplProvider> getProvider(Class<?> implClass) {
        if (mApiImpsWithProviderMap.isEmpty()) return null;
        synchronized (mApiImpsWithProviderMap) {
            return mApiImpsWithProviderMap.get(implClass);
        }
    }

}
